﻿//
// Created by hujin on 2020/10/6.
//

#ifndef C_MIPS_CMPLR_SYMBOLTABLE_H
#define C_MIPS_CMPLR_SYMBOLTABLE_H

#include <map>
#include <stack>
#include <vector>
#include <string>
class ParamsNode;

enum ID_Type {
	ID_NULL, ID_CNST_C, ID_CNST_I, ID_VAR_C, ID_VAR_I,
	ID_ARR_C, ID_ARR_I, ID_ARR_2_C, ID_ARR_2_I,
	ID_FUNC_C, ID_FUNC_I, ID_VOID
};
class ParamsNode;
struct Identifier_Data {
	ID_Type type = ID_CNST_C;
	ParamsNode* paramsNode = nullptr;
    int cnstData = 0;
    int size[2] = {};
	int uid = 0;
	bool global = false;
	Identifier_Data() = default;

	explicit Identifier_Data(ID_Type type) : type(type) {}

	Identifier_Data(ID_Type type, ParamsNode* paramsNode) : type(type), paramsNode(paramsNode) {}
};
class SymbolTable {

	std::vector<std::map<std::string, Identifier_Data>> table;

	int stackLevel = 0;
	int uidpos = 0;
	int uidTempPos = 0;
	int labelPos = 0;
public:
	SymbolTable() = default;

	bool pushSymbol(const std::string& name, const Identifier_Data& type);
	bool containsSymbol(std::string& name);
	int getIDCnt() const{return uidpos +1;}

    int gettempVarID() {return --uidTempPos;}
    int getVarID() {return ++uidpos;}
    int getLabel(){return ++labelPos;}

	Identifier_Data getDiscriptions(const std::basic_string<char>& name);
	void pushStack();
	void popStack();

};

#endif //C_MIPS_CMPLR_SYMBOLTABLE_H
